﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace GogTasks.UserControls
{
    /// <summary>
    /// The inner panel is a partial visible panel which is scrolled with the finger, allowing
    /// the user to see a window of the panel behind at all times
    /// </summary>
    public partial class ScrollablePanel : UserControl , IAddableControl
    {
        private int MaxBottom;
        private int MaxRight;
        public delegate void ControlEventHandler(object sender, ControlEventArgs args);
        public event ControlEventHandler ControlAdded;
        public event EventHandler ControlsClearing;

        private int ScrollY = 0;

        public ScrollablePanel()
        {
            InitializeComponent();
            //if (!Context.EnableFingerScroll) base.AutoScroll = true;
        }

        /// <summary>
        /// Controls on this panel. Exposes the controls of the inner panel.
        /// </summary>
        public ControlCollection InnerControls
        {
            get
            {
                return ThePanel.Controls;
            }
        }

        public Panel InnerPanel { get { return ThePanel; } }

        /// <summary>
        /// Clears the controls on this panel
        /// </summary>
        public void ClearControls()
        {
            OnControlsClearing();
            ThePanel.Controls.Clear();
            ThePanel.Location = new Point(0,0);
            ResetInnerPanelSize();
            MaxRight = 0;
            MaxBottom = 0;
        }

        public void AddControl(Control control)
        {
            if (MaxBottom < control.Bottom) MaxBottom = control.Bottom;
            if (MaxRight < control.Right) MaxRight = control.Right;

            int innerWidth = Math.Max(Width, MaxRight);
            int innerHeight = Math.Max(Height, MaxBottom);

            ThePanel.Size = new Size(innerWidth, innerHeight);
            ThePanel.Controls.Add(control);
            OnControlAdded(control);
        }

        public void RemoveControl (Control control)
        {
            // Todo: implement correctly - max and minbottom mustbe corrected
            ThePanel.Controls.Remove(control);
            ResetInnerPanelSize();
        }

        /// <summary>
        /// Returns the list of controls on the inner panel
        /// </summary>
        public ControlCollection GetControls()
        {
            return InnerControls;
        }

        private void OnControlAdded(Control control)
        {
            if (ControlAdded != null) 
                ControlAdded.Invoke(this, new ControlEventArgs(control));
        }

        private void OnControlsClearing()
        {
            if (ControlsClearing != null) 
                ControlsClearing.Invoke(this, new EventArgs());
        }

        public void ResetInnerPanelSize()
        {
            ThePanel.Height = Height;
            ThePanel.Width = Width;
        }

        private void Scroll(int scrollDelta)
        {
            ScrollTo(ScrollY + scrollDelta);
        }
        
        public void ScrollTo(int y)
        {
            int max = ThePanel.Height - this.Height;
            if (y < 0) y = 0;
            if (y > max) y = max;
            //Context.DebugWrite("ScrollTo: " + y + ", ScrollY: " + ScrollY + ", max: " + max);
            ScrollY = y;

            ThePanel.Location = new Point(0, 0 - ScrollY);
        }

        private void ScrollablePanel_MouseDown(object sender, MouseEventArgs e)
        {
        }


        private void ScrollablePanel_ParentChanged(object sender, EventArgs e)
        {
            ThePanel.BackColor = BackColor;
        }


        private void panelFingerScrollExtender_Pan(object sender, PanEventArgs e)
        {
            Scroll(0- e.PanY);
        }

        #region Event propagation
        private void ThePanel_MouseDown(object sender, MouseEventArgs e)
        {
            OnMouseDown(e);
        }

        private void ThePanel_MouseMove(object sender, MouseEventArgs e)
        {
            OnMouseMove(e);
        }

        private void ThePanel_MouseUp(object sender, MouseEventArgs e)
        {
            OnMouseUp(e);
        }

        private void ThePanel_Click(object sender, EventArgs e)
        {
            OnClick(e);
        }

        private void ThePanel_DoubleClick(object sender, EventArgs e)
        {
            OnDoubleClick(e);
        }
        #endregion
    }

    public class ControlEventArgs : EventArgs
    {
        public Control Control { get; set; }
        public ControlEventArgs(Control c) { Control = c; }
    }

}
